/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.homullus;

import org.lwjgl.opengl.*;
import org.lwjgl.util.glu.tessellation.*;
import org.lwjgl.util.vector.Vector3f;

/**
 *
 * @author Gary
 */
public class Cube
{
    private boolean wireframe = false;
    public void SetWireframe(boolean b) {  wireframe = b; }
    public boolean IsWireframe() { return wireframe; }

    public void Draw(float x1, float y1, float z1,
                     float x2, float y2, float z2,
                     float w, float l)
    {

        if (FloatEquality(x1,x2,0.001f) && FloatEquality(z1,z2,0.001f))
            DrawYAlignedCube(x1,y1,z1,x2,y2,z2,w,l);
        else if (FloatEquality(y1,y2,0.001f) && FloatEquality(z1,z2,0.001f))
            DrawXAlignedCube(x1,y1,z1,x2,y2,z2,w,l);
        else if (FloatEquality(x1,x2,0.001f) && FloatEquality(y1,y2,0.001f))
            DrawZAlignedCube(x1,y1,z1,x2,y2,z2,w,l);

        

    }

    

    private void DrawXAlignedCube(float x1, float y1, float z1,
                     float x2, float y2, float z2,
                     float w, float l)
    {
        float hw = w/2;
        float hl = l/2;
        Vector3f A = new Vector3f(x1, y1 - hl, z1 - hw);
        Vector3f B = new Vector3f(x1, y1 - hl, z1 + hw);
        Vector3f C = new Vector3f(x1, y1 + hl, z1 + hw);
        Vector3f D = new Vector3f(x1, y1 + hl, z1 - hw);

        Vector3f E = new Vector3f(x2,y2 - hl,z2-hw);
        Vector3f F = new Vector3f(x2,y2 - hl,z2+hw);
        Vector3f G = new Vector3f(x2,y2 + hl,z2+hw);
        Vector3f H = new Vector3f(x2,y2 + hl,z2-hw);
        DrawCube(A, B, C, D, E, F, G, H);
        
    }

    private void DrawYAlignedCube(float x1, float y1, float z1,
                     float x2, float y2, float z2,
                     float w, float l)
    {
        float hw = w/2;
        float hl = l/2;
        Vector3f A = new Vector3f(x1 - hl, y1, z1 - hw);
        Vector3f B = new Vector3f(x1 - hl, y1, z1 + hw);
        Vector3f C = new Vector3f(x1 + hl, y1, z1 + hw);
        Vector3f D = new Vector3f(x1 + hl, y1, z1 - hw);

        Vector3f E = new Vector3f(x2-hl,y2,z2-hw);
        Vector3f F = new Vector3f(x2-hl,y2,z2+hw);
        Vector3f G = new Vector3f(x2+hl,y2,z2+hw);
        Vector3f H = new Vector3f(x2+hl,y2,z2-hw);
        DrawCube(A, B, C, D, E, F, G, H);
    }

    private void DrawZAlignedCube(float x1, float y1, float z1,
                     float x2, float y2, float z2,
                     float w, float l)
    {
        float hw = w/2;
        float hl = l/2;
        Vector3f A = new Vector3f(x1 - hl, y1 - hw, z1);
        Vector3f B = new Vector3f(x1 - hl, y1 + hw, z1);
        Vector3f C = new Vector3f(x1 + hl, y1 + hw, z1);
        Vector3f D = new Vector3f(x1 + hl, y1 - hw, z1);

        Vector3f E = new Vector3f(x2-hl,y2-hw,z2);
        Vector3f F = new Vector3f(x2-hl,y2+hw,z2);
        Vector3f G = new Vector3f(x2+hl,y2+hw,z2);
        Vector3f H = new Vector3f(x2+hl,y2-hw,z2);
        DrawCube(A, B, C, D, E, F, G, H);
    }

    private void DrawCube(Vector3f A, Vector3f B, Vector3f C, Vector3f D,
                          Vector3f E, Vector3f F, Vector3f G, Vector3f H)
    {
        if (IsWireframe())
        {
            GL11.glBegin(GL11.GL_LINES);
              //top
              GL11.glVertex3f(A.x,A.y,A.z);
              GL11.glVertex3f(B.x,B.y,B.z);

              GL11.glVertex3f(B.x,B.y,B.z);
              GL11.glVertex3f(C.x,C.y,C.z);

              GL11.glVertex3f(C.x,C.y,C.z);
              GL11.glVertex3f(D.x,D.y,D.z);

              GL11.glVertex3f(D.x,D.y,D.z);
              GL11.glVertex3f(A.x,A.y,A.z);

              //side
              GL11.glVertex3f(A.x,A.y,A.z);
              GL11.glVertex3f(E.x,E.y,E.z);

              GL11.glVertex3f(B.x,B.y,B.z);
              GL11.glVertex3f(F.x,F.y,F.z);

              GL11.glVertex3f(C.x,C.y,C.z);
              GL11.glVertex3f(G.x,G.y,G.z);

              GL11.glVertex3f(D.x,D.y,D.z);
              GL11.glVertex3f(H.x,H.y,H.z);

              //bottom
              GL11.glVertex3f(E.x,E.y,E.z);
              GL11.glVertex3f(F.x,F.y,F.z);

              GL11.glVertex3f(F.x,F.y,F.z);
              GL11.glVertex3f(G.x,G.y,G.z);

              GL11.glVertex3f(G.x,G.y,G.z);
              GL11.glVertex3f(H.x,H.y,H.z);

              GL11.glVertex3f(H.x,H.y,H.z);
              GL11.glVertex3f(E.x,E.y,E.z);

            GL11.glEnd();
        }
        else
        {
            GL11.glBegin(GL11.GL_QUADS);
              //top
              GL11.glVertex3f(A.x,A.y,A.z);
              GL11.glVertex3f(B.x,B.y,B.z);
              GL11.glVertex3f(C.x,C.y,C.z);
              GL11.glVertex3f(D.x,D.y,D.z);

              //side
              GL11.glVertex3f(A.x,A.y,A.z);
              GL11.glVertex3f(B.x,B.y,B.z);
              GL11.glVertex3f(F.x,F.y,F.z);
              GL11.glVertex3f(E.x,E.y,E.z);

              GL11.glVertex3f(B.x,B.y,B.z);
              GL11.glVertex3f(C.x,C.y,C.z);
              GL11.glVertex3f(G.x,G.y,G.z);
              GL11.glVertex3f(F.x,F.y,F.z);

              GL11.glVertex3f(C.x,C.y,C.z);
              GL11.glVertex3f(D.x,D.y,D.z);
              GL11.glVertex3f(H.x,H.y,H.z);
              GL11.glVertex3f(G.x,G.y,G.z);

              GL11.glVertex3f(D.x,D.y,D.z);
              GL11.glVertex3f(H.x,H.y,H.z);
              GL11.glVertex3f(E.x,E.y,E.z);
              GL11.glVertex3f(A.x,A.y,A.z);

              //bottom
              GL11.glVertex3f(E.x,E.y,E.z);
              GL11.glVertex3f(F.x,F.y,F.z);
              GL11.glVertex3f(G.x,G.y,G.z);
              GL11.glVertex3f(H.x,H.y,H.z);

            GL11.glEnd();
        }
    }


    private void glVertex3f(Vector3f v)
    {
        GL11.glVertex3f(v.x,v.y, v.z);
    }

    private boolean  FloatEquality(float left, float right, float diff)
    {
        return (Math.abs(left - right) <= diff);
    }
}
